﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Xml.Linq;

namespace Shiny.SmartTravel.Data.Local
{
    /// <summary>
    /// A Sight entity for local
    /// </summary>
    public class Sight : INotifyPropertyChanged
    {
        /// <summary>
        /// empty ctor.
        /// </summary>
        public Sight() { }

        /// <summary>
        /// Gets or sets the unique id of a Sight object
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// Gets or sets the province id .
        /// </summary>
        public int ProvinceId { get; set; }

        /// <summary>
        /// Gets or sets the city id
        /// </summary>
        public int CityId { get; set; }

        /// <summary>
        /// Gets or sets the parent sight id if a sight is a small one.
        /// </summary>
        public int ParentSightId { get; set; }

        /// <summary>
        /// Gets or sets a boolean value indicates wheather the Sight is small or not
        /// </summary>
        public bool IsSmall { get; set; }

        private string name;

        /// <summary>
        /// Gets or sets the name of a sight
        /// </summary>
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }

        /// <summary>
        /// Gets or sets the uri name
        /// </summary>
        public string UriName { get; set; }

        /// <summary>
        /// Gets or sets the image uri string
        /// </summary>
        public string Image { get; set; }

        /// <summary>
        /// Gets or sets a string value indicates that the domain used by a big sight
        /// </summary>
        public string Domain { get; set; }

        private string intro;
        /// <summary>
        /// Gets or sets the intro of a City object
        /// </summary>
        public string Intro
        {
            get { return intro; }
            set
            {
                intro = value;
                OnPropertyChanged("Intro");
            }
        }
        #region INotifyPropertyChanged Members

        /// <summary>
        /// Property changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        /// <summary>
        /// Notify
        /// </summary>
        /// <param name="name"></param>
        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(name));
        }

        /// <summary>
        /// Gets the Name of a Sight
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.Name;
        }
    }

    /// <summary>
    /// A sight collection
    /// </summary>
    public class SightsCollection : ObservableCollection<Sight>
    {
        private string dataFile = "Sights.xml";

        /// <summary>
        /// All sights
        /// </summary>
        public SightsCollection()
        {
            try
            {
                IEnumerable<Sight> sights = LoadAllSights();

                foreach (var s in sights)
                {
                    Add(s);
                }
            }
            catch (Exception ex)
            {
                throw new LocalDataException("LocalData Error! Please DO NOT modify the files under LocalData folder, great thanks.", ex);
            }
        }

        /// <summary>
        /// Initialize SightsCollection by specify the city id
        /// </summary>
        /// <param name="cityId"></param>
        public SightsCollection(int cityId)
        {
            try
            {
                IEnumerable<Sight> sights = LoadSightsByCityId(cityId);

                foreach (var s in sights)
                {
                    Add(s);
                }
            }
            catch (Exception ex)
            {
                throw new LocalDataException("LocalData Error! Please DO NOT modify the files under LocalData folder, great thanks.", ex);
            }
        }

        private IEnumerable<Sight> LoadSightsByCityId(int cityId)
        {
            string path = string.Format("{0}\\{1}", Settings.LocalDataFolder, dataFile);
            XDocument xdoc = XDocument.Load(path);
            IEnumerable<Sight> sights = from s in xdoc.Element("XutourSights").Elements("Sight")
                                        where (int)s.Element("CityId") == cityId
                                        select new Sight { Id = (int)s.Element("Id"), ProvinceId = (int)s.Element("ProvinceId"), CityId = (int)s.Element("CityId"), ParentSightId = (int)s.Element("ParentSightId"), IsSmall = (bool)s.Element("IsSmall"), Name = (string)s.Element("Name"), Image = (string)s.Element("Image"), Intro = (string)s.Element("Intro"), UriName = (string)s.Element("UriName"), Domain = (string)s.Element("Domain") };
            return sights;
        }

        private IEnumerable<Sight> LoadAllSights()
        {
            string path = string.Format("{0}\\{1}", Settings.LocalDataFolder, dataFile);
            XDocument xdoc = XDocument.Load(path);
            IEnumerable<Sight> sights = from s in xdoc.Element("XutourSights").Elements("Sight")
                                        select new Sight { Id = (int)s.Element("Id"), ProvinceId = (int)s.Element("ProvinceId"), CityId = (int)s.Element("CityId"), ParentSightId = (int)s.Element("ParentSightId"), IsSmall = (bool)s.Element("IsSmall"), Name = (string)s.Element("Name"), Image = (string)s.Element("Image"), Intro = (string)s.Element("Intro"), UriName = (string)s.Element("UriName"), Domain = (string)s.Element("Domain") };
            return sights;
        }
    }
}
